home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 20 / Cream of the Crop 20 (Terry Blount) (1996).iso / os2 / rsynth21.zip / aufile.c < prev    next >
Text File  |  1996-07-19  |  7KB  |  320 lines

  1. #include <config.h>
  2. #include "proto.h"
  3. #include <stdio.h>
  4. #include <fcntl.h>
  5. #include <useconfig.h>
  6. #include "getargs.h"
  7. #include "l2u.h"
  8. #include "hplay.h"
  9. #include "file.h"
  10.  
  11. #define SUN_MAGIC     0x2e736e64        /* Really '.snd' */
  12. #define SUN_HDRSIZE    24            /* Size of minimal header */
  13. #define SUN_UNSPEC    ((unsigned)(~0))    /* Unspecified data size */
  14. #define SUN_ULAW    1            /* u-law encoding */
  15. #define SUN_LIN_8    2            /* Linear 8 bits */
  16. #define SUN_LIN_16    3            /* Linear 16 bits */
  17.  
  18. file_write_p file_write = NULL;
  19. file_term_p  file_term  = NULL;
  20.  
  21. static char *linear_file;
  22. static char *au_file;
  23. static char *wav_file;
  24. static int au_fd = -1;            /* file descriptor for .au ulaw file */
  25. static int linear_fd = -1;
  26. static int wav_fd = -1;
  27.  
  28. static unsigned au_encoding = SUN_ULAW;
  29. static unsigned au_size = 0;
  30. static unsigned wav_size = 0;
  31.  
  32. static void wblong PROTO((int fd, unsigned long x));
  33. static void 
  34. wblong(fd, x)
  35. int fd;
  36. unsigned long x;
  37. {
  38.  int i;
  39.  for (i = 24; i >= 0; i -= 8)
  40.   {
  41.    char byte = (char) ((x >> i) & 0xFF);
  42.    write(fd, &byte, 1);
  43.   }
  44. }
  45.  
  46. static void walong PROTO((int fd, unsigned long x));
  47. static void 
  48. walong(fd, x)
  49. int fd;
  50. unsigned long x;
  51. {
  52.  int i;
  53.  for (i = 0; i <= 24; i += 8)
  54.   {
  55.    unsigned char byte = (unsigned char) ((x >> i) & 0xFF);
  56.    write(fd, &byte, 1);
  57.   }
  58. }
  59.  
  60.  
  61. extern void au_header PROTO((int fd,unsigned enc,unsigned rate,unsigned size,char *comment));
  62.  
  63. void 
  64. au_header(fd, enc, rate, size, comment)
  65. int fd;
  66. unsigned enc;
  67. unsigned rate;
  68. unsigned size;
  69. char *comment;
  70. {
  71.  if (!comment)
  72.   comment = "";
  73.  wblong(fd, SUN_MAGIC);
  74.  wblong(fd, SUN_HDRSIZE + strlen(comment));
  75.  wblong(fd, size);
  76.  wblong(fd, enc);
  77.  wblong(fd, rate);
  78.  wblong(fd, 1);                   /* channels */
  79.  write(fd, comment, strlen(comment));
  80. }
  81.  
  82. void WriteWaveHeader(int fh, int n)
  83. {
  84.     long bl;
  85.     int  bi;
  86.  
  87.     write(fh, "RIFF",4);    // Write "RIFF"
  88.     bl  = n;
  89.     bl += 36L;
  90.     walong(fh,bl);     // Write Size of file with header
  91.     write(fh, "WAVE",4);    // Write "WAVE"
  92.     write(fh, "fmt ",4);    // Write "fmt "
  93.     bl = 0x00000010;
  94.     walong(fh,bl);    // Size of previous header (fixed)
  95.     bl = 0x00010001;
  96.     walong(fh, bl);    // formatTag and nChannels
  97.     bl = samp_rate;     
  98.     walong(fh, bl);    // nSamplesPerSec
  99.     walong(fh, bl);     // nAvgBytesPerSec
  100.     bl = 0x00080001;
  101.     walong(fh,bl);      // nBlockAlign (always 1?) / nBitsPerSample
  102.     write(fh,"data",4);     // Write "data"
  103.     bl = n;
  104.     walong(fh, bl);    // True length of sample data
  105. }
  106.  
  107. static void aufile_write PROTO((int n,short *data));
  108.  
  109. static void
  110. aufile_write(n, data)
  111. int n;
  112. short *data;
  113. {
  114.  if (n > 0)
  115.   {
  116.    if (linear_fd >= 0)
  117.     {
  118.      unsigned size = n * sizeof(short);
  119.      if (write(linear_fd, data, n * sizeof(short)) != size)
  120.             perror("write");
  121.     }
  122.    if (au_fd >= 0)
  123.     {
  124.      if (au_encoding == SUN_LIN_16)
  125.       {
  126.        unsigned size = n * sizeof(short);
  127.        if (write(au_fd, data, size) != size)
  128.         perror("write");
  129.        else
  130.         au_size += size;
  131.       }
  132.      else if (au_encoding == SUN_ULAW)
  133.       {
  134.        unsigned char *plabuf = (unsigned char *) malloc(n);
  135.        if (plabuf)
  136.         {
  137.          unsigned char *p = plabuf;
  138.          unsigned char *e = p + n;
  139.          while (p < e)
  140.           {
  141.            *p++ = short2ulaw(*data++);
  142.           }
  143.          if (write(au_fd, plabuf, n) != n)
  144.           perror(au_file);
  145.          else
  146.           au_size += n;
  147.          free(plabuf);
  148.         }
  149.        else
  150.         {
  151.          fprintf(stderr, "%s : No memory for ulaw data\n", program);
  152.         }
  153.       }
  154.      else
  155.       {
  156.        abort();
  157.       }
  158.     }
  159.   }
  160.  if (wav_fd >= 0)
  161.   {
  162.     unsigned char *plabuf = (unsigned char *) malloc(n);
  163.     WriteWaveHeader(wav_fd,n);
  164.     if (plabuf)
  165.       {
  166.         unsigned char *p = plabuf;
  167.         unsigned char *e = p + n;
  168.         while (p < e)
  169.          {
  170.           *data /= 128  ;
  171.           *p = *data + 128;
  172.            p++;
  173.            data++;
  174.           }
  175.         if (write(wav_fd, plabuf, n) != n)
  176.           perror(wav_file);
  177.        else 
  178.           wav_size += n;
  179.        free(plabuf);
  180.       }
  181.      else
  182.       {
  183.        fprintf(stderr, "%s : No memory for wav data\n", program);
  184.        return;
  185.       }
  186.   }
  187. }
  188.  
  189. static void aufile_term PROTO((void));
  190.  
  191. static void
  192. aufile_term()
  193. {
  194.  /* Finish ulaw file */
  195.  if (au_fd >= 0)
  196.   {
  197.    off_t here = lseek(au_fd, 0L, SEEK_CUR);
  198.    if (here >= 0)
  199.     {
  200.      /* can seek this file - truncate it */
  201.      ftruncate(au_fd, here);
  202.      /* Now go back and overwite header with actual size */
  203.      if (lseek(au_fd, 8L, SEEK_SET) == 8)
  204.       {
  205.        wblong(au_fd, au_size);
  206.       }
  207.     }
  208.    if (au_fd != 1)
  209.     close(au_fd);
  210.    au_fd = -1;
  211.   }
  212.  /* Finish linear file */
  213.  if (linear_fd >= 0)
  214.   {
  215.    ftruncate(linear_fd, lseek(linear_fd, 0L, SEEK_CUR));
  216.    if (linear_fd != 1)
  217.     close(linear_fd);
  218.    linear_fd = -1;
  219.   }
  220. /* finish WAV file */
  221.  if (wav_fd >= 0)
  222.   {
  223.    off_t here = lseek(wav_fd, 0L, SEEK_CUR);
  224.    if (here >= 0)
  225.     {
  226.      /* can seek this file - truncate it */
  227.      ftruncate(wav_fd, here);
  228.      /* Now go back and overwite header with actual size */
  229.      if (lseek(wav_fd, 4L, SEEK_SET) == 4)
  230.       {
  231.        walong(wav_fd, wav_size+36);
  232.       }
  233.      if (lseek(wav_fd, 40L, SEEK_SET) == 40)
  234.       {
  235.        walong(wav_fd, wav_size);
  236.       }
  237.  
  238.     }
  239.    if (wav_fd != 1)
  240.     close(wav_fd);
  241.    wav_fd = -1;
  242.   }
  243.  
  244. }
  245.  
  246.  
  247. int
  248. file_init(argc, argv)
  249. int argc;
  250. char *argv[];
  251. {
  252.  argc = getargs("File output", argc, argv,
  253.                 "l", "", &linear_file, "Raw 16-bit linear pathname",
  254.                 "o", "", &au_file,     "Sun/Next audio file name",
  255.                 "w", "", &wav_file,    "OS/2 WAV File name",
  256.                 NULL);
  257.  if (help_only)
  258.   return argc;
  259.  
  260.  if (au_file)
  261.   {
  262.    if (strcmp(au_file, "-") == 0)
  263.     {
  264.      au_fd = 1;                   /* stdout */
  265.     }
  266.    else
  267.     {
  268.      au_fd = open(au_file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
  269.      if (au_fd < 0)
  270.       perror(au_file);
  271.     }
  272.    if (au_fd >= 0)
  273.     {
  274.      if (samp_rate > 8000)
  275.       au_encoding = SUN_LIN_16;
  276.      else
  277.       au_encoding = SUN_ULAW;
  278.      au_header(au_fd, au_encoding, samp_rate, SUN_UNSPEC, "");
  279.      au_size = 0;
  280.     }
  281.   }
  282.  
  283.  if (linear_file)
  284.   {
  285.    if (strcmp(linear_file, "-") == 0)
  286.     {
  287.      linear_fd = 1 /* stdout */ ;
  288.     }
  289.    else
  290.     {
  291.      linear_fd = open(linear_file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
  292.      if (linear_fd < 0)
  293.       perror(linear_file);
  294.     }
  295.   }
  296.  if (wav_file)
  297.   {
  298.    if (strcmp(wav_file, "-") == 0)
  299.     {
  300.      wav_fd = 1 /* stdout */ ;
  301.     }
  302.    else
  303.     {
  304.      wav_fd = open(wav_file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
  305.      if (wav_fd < 0)
  306.       perror(wav_file);
  307.     }
  308.   }
  309.  
  310.  
  311.  if (au_fd >= 0 || linear_fd >= 0 || wav_fd > 0)
  312.   {
  313.    file_write = aufile_write;
  314.    file_term  = aufile_term;
  315.   }
  316.  return argc;
  317. }
  318.  
  319.  
  320.